const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')

module.exports = {
    entry: './src/js/index',

    output: {
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build'),
        chunkFilename: 'js/[name].[contenthash:10]_chunk.js'
    },

    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    },

    plugins: [
        new HtmlWebpackPlugin()
    ],

    mode: 'production',

    resolve: {
        alias: {
            $css: resolve(__dirname, '/src/css')
        },

        extensions: ['.js', '.json', '.css'],

        modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
    },

    optimization: {
        splitChunks: {
            chunks: 'all',
            // 默认值，可以不写
            /*// 分割的最小 chunk 为 30kb
            minSize: 30 * 1024,

            // 最大没有限制
            maxSize: 0,

            // 要提取的 chunk 最少被引用一次
            minChunks: 1,

            // 按需加载时并行加载的文件的最大数量
            maxAsyncRequests: 5,

            // 入口 js 文件最大并行请求数量
            maxInitialRequests: 3,

            // 名称连接符
            automaticNameDelimiter: '~',

            // 可是使用命名规则
            name: true,

            // 分割 chunk 的组
            cacheGroups: {
                /!*
                    node_modules 文件会被打包到 vendors 组的 chunk 中， --> vendors~xxx.js
                    满足上面的公共规则
                 *!/
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    // 优先级
                    priority: -10
                },

                default: {
                    // 要提取的 chunk 至少被引用两次
                    minChunks: 2,

                    // 优先级
                    priority: -20,

                    // 如果当前要打包的模块，和之前已经被提取的模块是同一个，就会复用，而不是重新打包模块
                    reuseExistingChunk: true
                }
            }*/
        },

        /*
            将当前模块的记录其他模块的 hash 单独打包为一个 runtime
            解决：修改 a 文件导致 b 文件的 contenthash 变化
         */
        runtimeChunk: {
            name: entrypoint => `runtime-${entrypoint.name}`
        },

        minimizer: [
            // 配置生产环境的压缩方案：js 和 css
            new TerserWebpackPlugin({
                // 开启缓存
                cache: true,

                // 开启多进程打包
                parallel: true,

                // 启用source-map
                sourceMap: true
            })
        ]
    }
}

